﻿using ZeroSum.IdGenerator.Configurations;

namespace ZeroSum.IdGenerator.Core;

/// <summary>
///     常规雪花算法
/// </summary>
internal class SnowWorkerM2 : SnowWorkerM1
{
    public SnowWorkerM2(IdGeneratorOptions options) : base(options)
    {
    }

    public override long NextId()
    {
        lock (SyncLock)
        {
            var currentTimeTick = GetCurrentTimeTick();

            if (LastTimeTick == currentTimeTick)
            {
                if (CurrentSeqNumber++ > MaxSeqNumber)
                {
                    CurrentSeqNumber = MinSeqNumber;
                    currentTimeTick = GetNextTimeTick();
                }
            }
            else
            {
                CurrentSeqNumber = MinSeqNumber;
            }

            if (currentTimeTick < LastTimeTick)
                throw new Exception($"Time error for {LastTimeTick - currentTimeTick} milliseconds");

            LastTimeTick = currentTimeTick;
            var result = (currentTimeTick << TimestampShift) + ((long) WorkerId << SeqBitLength) + CurrentSeqNumber;

            return result;
        }
    }
}